Overwatch

Overwatch is a team-based multiplayer first-person shooter with a player base of around 10 million players per month. Each match sees a uniquely chosen set of heroes go head to head in a 6v6 battle. Players can choose from 32 heroes belonging to 3 main classes, tank, damage and support. Each team is allowed two heroes from each class. The composition of heroes on a team greatly alters

players have to choose which class to queue in before joining a game meaning once in a game they can only choose from the heroes in the class that they queued in

Data Origin

The data set used was scraped from Overbuff created March 24th spanning three months back - competitive

#Load the data set
df = read.csv("hero_stats_3_months.csv")
#Transform original data set to only include the hero and 
df1 <- df %>% select(1, 2, 6, 10, 14, 18, 22, 26)

#Create a variable that is the sum of pick rate across all divisions so that visualisaion 1 can be ordered as desired
df1$totalpick <- rowSums(df1[,c(2:8)])

#Transform df1 to arrange heroes by total pick rate to create the desired order in the visualisation (adding traces in a loop overrides the 'reorder' function in plotly)
dfp1 <- df1 %>% arrange(desc(totalpick))

Visualisation 1 - Comparing Pick Rate Across Divisions

Need to mention that a grouped bar chart would be better per that article (on brave browser) but too many on the x axis to have a grouped. to combat the issue that stacked bar charts introduced this visualistion was made with plotly to facicilaite hover labels

A stacked bar chart will show a stand out trend of what hereos are picked more overall across all divisions. A more detailed look at the visualisation will show the differences in pick rate of each hero across the 7 divisions. Using plotly to create the visualisation (instead of ggplot) allows the use of the hover label feature. This feature is especially useful with stacked bar charts as many bars do not have a 0 starting point making it hard to determine the value that the bar represents.

#Set the plot space and add the first division
p1 <- plot_ly(dfp1, x = ~hero,
                    y = ~bronze_pick_rate, 
                    name = "Bronze Pick Rate",
                    type = "bar", 
                    width = 900,
                    height = 600,
                    #Set the colour of the first division and create a black line around each bar
                    marker = list(color = "#E0B5AC",
                                  line = list(color = "#000000, 0.5)",
                                  width = 1))) %>%

  #Set the layout specifications of the visualisation
  layout(title = "Hero Pick Rate by Division",
                      #Set the order of the heroes to be determined by the order they appear in the dataset
         xaxis = list(categoryarray = ~hero, 
                      categoryorder = "array",
                      #Set the x axis title and the angle and size of the labels for each hero
                      title = "Hero",
                      tickangle =270),
                      tickfont = list(size = 10),
                      #Set the y axis title, scale format, range and type of bar chart
         yaxis = list(title = "Pick Rate", 
                      tickformat = "%",
                      range = c(0, 0.70)),
                      barmode = "stack")
#Create a value containing the 6 divisions not yet plotted for use in a for loop
  divplot <- colnames(dfp1[c(3:8)])
#Create a value for use in the add trace loop to set the colours for each division (colours match the exact hex codes that Overbuff assigned to each division)
  colours <- c("#CAD6CC", "#EFEB8B", "#4E98BB", "#D9E8F3", "#EDA152", "#FEE072")
#Create a loop to add a trace for each of the remaining divisions
  for(i in divplot){
    p1 <- p1 %>% add_trace(x = dfp1[["hero"]], 
                           y = dfp1[[i]],
                           #Replace "_" with " " and capitalise the division titles
                           name = gsub(x = i, pattern = "\\_", replacement = " ") %>% str_to_title(i),
                           #Change the colours of the divisions per the "colours" variable previously created
                           marker = list(color = colours[[match(i, divplot)]]))
  }
#Display p1 visualisation  
p1

Create second visualisation as a slope graph so no exact figures but clearer visualisation of the rankings of pick in lower and higher elos

dfp2wide <- df %>% select(1, 2, 26)

dfp2long <- gather(dfp2wide, division, pick_rate, bronze_pick_rate, grandmaster_pick_rate, factor_key = TRUE)

dfp2 <- dfp2long %>%
        group_by(division) %>%
        arrange(division, desc(pick_rate), hero) %>% 
        mutate(rank = row_number()) %>%
        ungroup()


p2 <- ggplot(dfp2, aes(x = division, y = rank, group = hero)) +
  
      geom_line(aes(color = hero, alpha = 1), size = 2) +
  
      geom_point(aes(color = hero, alpha = 1), size = 4) +
  
      geom_point(color = "#FFFFFF", size = 1) +
  
      geom_text(data = dfp2 %>% filter(division == "bronze_pick_rate"),
            aes(label = hero, x = 0.8) , hjust = 0.5,
            fontface = "bold", color = "#000000", size = 4) +
  
      geom_text(data = dfp2 %>% filter(division == "grandmaster_pick_rate"),
            aes(label = hero, x = 2.2) , hjust = 0.5,
            fontface = "bold", color = "#000000", size = 4) +
  
      scale_x_discrete(labels = c("Bronze Pick Rate Rank", "Grandmaster Pick Rate Rank")) +
  
      scale_y_reverse(breaks = 1:32) + 
  
      theme(plot.title = element_text(size=16, face = "bold"),
            
            axis.text.x = element_text(size=12),
            
            axis.title = element_text(size=14,face = "bold"),
            
            panel.grid.major.y = element_blank(),
            
            legend.position = "none") +
  
      labs(x = "Division", 
           y = "Hero Rank", 
           title = "Overwatch Hero Pick Rate",
           subtitle = "Hereos ranked by % pick rate in the lowest and highest divisions (Bronze and Grandmaster) over the last 3 months") +
   
      scale_color_manual(values = c("#2178E9", "#67121D", "#3EA2CB", "#6E994D", "#F3B23A", "#FF7FD1", "#DDCCAC", "#04ADEF", "#84FE01", "#938848", "#D39308", "#8BEC22", "#C83C3C", "#9ADBF4", "#FFE16C", "#B3365D", "#BCC84A", "#2178E9", "#A49D86", "#AA958E", "#C19477", "#5DAB81", "#5D81EB", "#A07DC8", "#5CECFF", "#FF6200", "#F8911B", "#7878D4", "#8991A6", "#4D7883", "#F571A8", "#C79C00")) 
  
  

p2